﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Security.Cryptography;
using MvcShop.Extensions.Encryption;

namespace MvcShop.MVC.Filters
{
    /// <summary>
    /// 防止恶意向服务器post数据
    /// </summary>
    public class AntiForgeryFilter : ActionFilterAttribute
    {
        /// <summary>
        /// 构造AntiForgeryFilter
        /// </summary>
        /// <param name="minutes">页面的有效时间</param>
        public AntiForgeryFilter(int minutes)
        {
            this._minutes = minutes;
        }

        int _minutes;
        long _ticks;
        AntiForgeryToken aft = new AntiForgeryToken();

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string formTicks = filterContext.HttpContext.Request.Form[AntiForgeryToken.TicksName];
            string formUtcTicks;
            try
            {
                formUtcTicks = aft.DecrypTick(formTicks);
            }
            catch (ArgumentException ex)
            {
                throw new ArgumentException(ex.Message);
            }
            catch (CryptographicException ex)
            {
                throw new CryptographicException(ex.Message);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

            if (!long.TryParse(formUtcTicks, out _ticks) || string.IsNullOrEmpty(formTicks))
            {
                throw new HttpAntiForgeryException("Bad Anti-Forgery Token");
            }

            TimeSpan timeOffset = new TimeSpan(aft.generateTicks() - _ticks);
            if (timeOffset.TotalMinutes > this._minutes)
            {
                throw new HttpAntiForgeryException("页面超时~!请刷新页面重试!");
            }

        }
    }
}
